Skip to content

Use new UI event to send a putative path to the system for opening #877

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jul 22, 2025

Conversation

jennybc
Copy link
Member

@jennybc jennybc commented Jul 19, 2025

Comment on lines -51 to -52
// TODO: What is the right thing to do outside of Positron when
// `options(browser =)` is called? Right now we error.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does anyone want me to hang onto this comment?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think so, we should only inject this option when launched from Positron. Probably an easy fix if you want to do it here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really follow how ark would hit ps_browse_url_impl() outside of Positron. Because I assume it works like this:

In Positron, ark takes charge of the "browser" option and that eventually routes through here.

But outside of Positron, ark would presumably have the default implementation of "browser", yeah?

Is the claim that ark would error outside of Positron actually true or true anymore? 🤔

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apparently I am wrong. Why do we set an option like "browser" in ark, but outside of Positron? This feels like it might be out of scope for this PR (a bigger problem). In which case I should just retain the comment and move on.

~/tmp % jupyter console --kernel=ark
Jupyter console 6.6.3


R version 4.4.2 (2024-10-31) -- "Pile of Leaves"
Copyright (C) 2024 The R Foundation for Statistical Computing
Platform: aarch64-apple-darwin20

R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.

  Natural language support but running in an English locale

R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.

Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.


In [1]: browseURL("~/tmp")
  2025-07-21T21:35:02.025887Z ERROR  No help port is available to check if '~/tmp' is a help url. Is the help comm open?
    at crates/ark/src/interface.rs:2032

  2025-07-21T21:35:02.026935Z ERROR  Failed to browse url due to: UI comm not connected, can't run `open_with_system`.
    at crates/ark/src/browser.rs:22


In [2]: getOption("browser")
Out[2]:
function(url) {
    .ps.Call("ps_browse_url", as.character(url))
}
<environment: 0x11fd5bc70>

Copy link
Member Author

@jennybc jennybc Jul 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are already tracking this problem here: #588.

So I'm going to merge this once the Positron side is approved.

Comment on lines -54 to -62
// For all other URLs, create a ShowUrl event and send it to the main
// thread; Positron will handle it.
let params = ShowUrlParams { url };
let event = UiFrontendEvent::ShowUrl(params);

let main = RMain::get();
let ui_comm_tx = main
.get_ui_comm_tx()
.ok_or_else(|| anyhow::anyhow!("UI comm not connected."))?;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code was basically duplicated in ps_ui_show_url() so now they share logic via the send_show_url_event() helper.

// This is probably a file path? Send to the front end and ask for system
// default opener.
log::trace!("Treating as file path and asking system to open");
let path = r_normalize_path(url.into())?;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The opener service on the Positron side expects a resolved path, so it's important to normalize on the backend.

Comment on lines -51 to -52
// TODO: What is the right thing to do outside of Positron when
// `options(browser =)` is called? Right now we error.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think so, we should only inject this option when launched from Positron. Probably an easy fix if you want to do it here?

Ok(R_NilValue)
}

pub fn send_open_with_system_default_event(path: &str) -> anyhow::Result<()> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Align with event name?

Suggested change
pub fn send_open_with_system_default_event(path: &str) -> anyhow::Result<()> {
pub fn send_open_with_system_event(path: &str) -> anyhow::Result<()> {

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like it. I'm implementing in a local commit, because I need to use "Rename Symbol" to also hit the call sites.

jennybc added a commit to posit-dev/positron that referenced this pull request Jul 22, 2025
Addresses #5486 
Companion PR in ark: posit-dev/ark#877

This PR creates a new event in the UI comm that says "open this thing
(file, presumably) with the default application according to the OS".

The immediate motivating example is to allow R's `browseURL()` to work
as expected in the Positron console.

### Release Notes

<!--
Optionally, replace `N/A` with text to be included in the next release
notes.
The `N/A` bullets are ignored. If you refer to one or more Positron
issues,
these issues are used to collect information about the feature or
bugfix, such
as the relevant language pack as determined by Github labels of type
`lang: `.
  The note will automatically be tagged with the language.

These notes are typically filled by the Positron team. If you are an
external
  contributor, you may ignore this section.
-->

#### New Features

- `browseURL()` in R now delegates to the operating system's default
opener for inputs that are not recognized as a web URL or an HTML file.

#### Bug Fixes

- N/A


### QA Notes

In R, use `browseURL()` on a local filepath. Exercise a couple of files
(meaning file types) and a folder. Here are examples taken from the "R
Code" column of the table at
#5486 (comment):

| R Code | Expectation in Positron R Console, with this PR + ark PR |
| -- | -- |
|`browseURL(tempdir())` | opens folder in OS's notion of file explorer
(e.g. Finder on macOS) |
| `temp_csv_file <- tempfile()` <br>`write.csv(iris,
temp_csv_file)` <br>`browseURL(temp_csv_file)` | opens the csv file in
OS's default application (for text files? on macOS, I'm getting
TextEdit) |
| `temp_csv_file_with_ext <- tempfile(fileext =
".csv")` <br>`write.csv(iris,
temp_csv_file_with_ext)` <br>`browseURL(temp_csv_file_with_ext)` | opens
the csv file in OS's default application for `.csv` (VS Code for me,
haha) |
| `temp_html_file <- tempfile()` <br>`writeLines("<p>Hi!</p>",
temp_html_file)` <br>`browseURL(temp_html_file)` | opens the html file
in OS's default application (for text files? on macOS, I'm getting
TextEdit) |
| `temp_html_file_with_ext <- tempfile(fileext =
".html")` <br>`writeLines("<p>Hi!</p>",
temp_html_file_with_ext)` <br>`browseURL(temp_html_file_with_ext)` |
opens `.html` file in default external browser |

When in doubt, the behaviour we seek is whatever happens in R in a plain
terminal or in RStudio Console.

We should definitely verify this on linux and Windows (I'm on macOS, so
feel pretty confident about that).

As for tests, I don't really know how we would do that 🤔 in this case.
The whole point is to open a file in *some other* application and
exactly what that is will vary by OS / user.

Signed-off-by: Jennifer (Jenny) Bryan <jenny.f.bryan@gmail.com>
@jennybc jennybc merged commit dad2c39 into main Jul 22, 2025
6 checks passed
@jennybc jennybc deleted the browseURL-for-files-etc branch July 22, 2025 14:44
@github-actions github-actions bot locked and limited conversation to collaborators Jul 22, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants